class UIGoods {
  constructor(g) {
    this.data = g;
    this._choose = 0;
  }

  get getTotalPrice() {
    return this.data.price * this.choose;
  }

  get isChoose() {
    return this.choose > 0;
  }

  get choose() {
    return Math.max(this._choose, 0);
  }

  set choose(num) {
    this._choose = num;
  }
}

class UIData {
  constructor() {
    this.uiCoods = goods.map((good) => new UIGoods(good));
    this.deliveryThreshold = 30;
    this.deliverPrice = 5;
  }

  get getTotalPrice() {
    return this.uiCoods.reduce((pre, cur) => (pre += cur.getTotalPrice), 0);
  }

  increase(index) {
    this.uiCoods[index].choose += 1;
  }

  decrease(index) {
    this.uiCoods[index].choose -= 1;
  }

  get getTotalChooseNumber() {
    return this.uiCoods.reduce((pre, cur) => (pre += cur.choose), 0);
  }

  get hasGoodsInCar() {
    return this.getTotalChooseNumber > 0;
  }

  get isCrossDeliveryThreshold() {
    return this.getTotalPrice >= this.deliveryThreshold;
  }

  isChoose(index) {
    return this.uiCoods[index].isChoose;
  }
}

// 整个界面
class UI {
  constructor() {
    this.uiData = new UIData();
    this.doms = {
      goodsContainerEl: document.querySelector(".goods-list"),
      deliverPriceEl: document.querySelector(".footer-car-tip"),
      footerPayEl: document.querySelector(".footer-pay"),
      footerPaySpanEl: document.querySelector(".footer-pay span"),
      totalPriceEl: document.querySelector(".footer-car-total"),
      carEl: document.querySelector(".footer-car"),
      badgeEl: document.querySelector(".footer-car-badge"),
    };

    const carRect = this.doms.carEl.getBoundingClientRect();
    this.jumpTarget = {
      x: carRect.left + carRect.width / 2,
      y: carRect.top + carRect.height / 5,
    };

    this.createHTML();
    this.updateFooter();
    this.listenEvent();
  }

  // 根据商品数据创建商品列表元素
  createHTML() {
    this.doms.goodsContainerEl.innerHTML = this.uiData.uiCoods
      .map(
        (g, i) =>
          `<div class="goods-item">
              <img src="${g.data.pic}" alt="" class="goods-pic" />
              <div class="goods-info">
                <h2 class="goods-title">${g.data.title}</h2>
                <p class="goods-desc">
                  ${g.data.desc}
                </p>
                <p class="goods-sell">
                  <span>月售 ${g.data.sellNumber}</span>
                  <span>好评率${g.data.favorRate}%</span>
                </p>
                <div class="goods-confirm">
                  <p class="goods-price">
                    <span class="goods-price-unit">￥</span>
                    <span>${g.data.price}</span>
                  </p>
                  <div class="goods-btns">
                    <i data-index="${i}" class="iconfont i-jianhao"></i>
                    <span>${g.choose}</span>
                    <i data-index="${i}" class="iconfont i-jiajianzujianjiahao"></i>
                  </div>
                </div>
              </div>
            </div>   
          `
      )
      .join("");
  }

  increase(index) {
    this.uiData.increase(index);
    this.updateGoodsItem(index);
    this.updateFooter();
    this.jump(index);
  }

  decrease(index) {
    this.uiData.decrease(index);
    this.updateGoodsItem(index);
    this.updateFooter();
  }

  updateGoodsItem(index) {
    const goodsDOM = this.doms.goodsContainerEl.children[index];
    if (this.uiData.isChoose(index)) {
      goodsDOM.classList.add("active");
    } else {
      goodsDOM.classList.remove("active");
    }

    const spanEl = goodsDOM.querySelector(".goods-confirm .goods-btns span");
    spanEl.textContent = this.uiData.uiCoods[index].choose;
  }

  updateFooter() {
    const total = this.uiData.getTotalPrice;

    this.doms.deliverPriceEl.textContent = `配送费￥${this.uiData.deliverPrice}`;
    if (this.uiData.isCrossDeliveryThreshold) {
      this.doms.footerPayEl.classList.add("active");
    } else {
      this.doms.footerPayEl.classList.remove("active");
      const dis = Math.round(this.uiData.deliveryThreshold - total);
      this.doms.footerPaySpanEl.textContent = `还差￥${dis}元起送`;
    }

    // 总价
    this.doms.totalPriceEl.textContent = total.toFixed(2);
    // 设置购物车的样式状态
    if (this.uiData.hasGoodsInCar) {
      this.doms.carEl.classList.add("active");
    } else {
      this.doms.carEl.classList.remove("active");
    }

    // 设置徽标数量
    this.doms.badgeEl.textContent = this.uiData.getTotalChooseNumber;
  }

  // 购物车动画
  carAnimate() {
    this.doms.carEl.classList.add("animate");
  }

  // 监听各种事件
  listenEvent() {
    this.doms.carEl.addEventListener("animationend", () => {
      this.doms.carEl.classList.remove("animate");
    });
  }

  jump(index) {
    const btnAddEl = this.doms.goodsContainerEl.children[index].querySelector(".i-jiajianzujianjiahao");
    const rect = btnAddEl.getBoundingClientRect();
    const start = {
      x: rect.left,
      y: rect.top,
    };

    const divEl = document.createElement("div");
    divEl.className = "add-to-car";
    const iEl = document.createElement("i");
    iEl.className = "iconfont i-jiajianzujianjiahao";
    // 设置初始位置
    divEl.style.transform = `translateX(${start.x}px)`; // x轴匀速移动
    iEl.style.transform = `translateY(${start.y}px)`;
    divEl.appendChild(iEl);
    document.body.appendChild(divEl);
    // 强行渲染
    divEl.clientWidth;

    // 设置目标位置
    divEl.style.transform = `translateX(${this.jumpTarget.x}px)`;
    iEl.style.transform = `translateY(${this.jumpTarget.y}px)`;

    // 动画结束后
    divEl.addEventListener(
      "transitionend",
      () => {
        divEl.remove();
        this.carAnimate();
      },
      {
        once: true, // 事件仅触发一次
      }
    );
  }
}

const ui = new UI();

// 事件
ui.doms.goodsContainerEl.addEventListener("click", (e) => {
  if (e.target.classList.contains("i-jiajianzujianjiahao")) {
    ui.increase(+e.target.dataset.index);
  } else if (e.target.classList.contains("i-jianhao")) {
    ui.decrease(+e.target.dataset.index);
  }
});
